Link to this headingOauth2
- Used for Authorization
- Enables third party application access to a limited version of the service
- “Login with Facebook”
Why is OAuth still hard in 2023?
Grant types
- Client Credentials: - Use if the Application is the Resource Owner
- Authorization Code: - If the application is a web app that is executing on the same server. Usually returns a Session token
- Resource Owner Password - If the Application can be trusted with the users credentials.
- Implicit: Used for Single Page Applications
- PKCE (Proof Key for Code Exchange): Used for native Application. Similar to Authorization Code
- OpenID Connect:
- Device Code:
- Hybrid:
Roles:
- Resource Owner: the entity that can grant access to a protected resource. Typically this is the end-user.
- Application: an application requesting access to a protected resource on behalf of the Resource Owner.
- Resource Server: the server hosting the protected resources. This is the API you want to access.
- Authorization Server: the server that authenticates the Resource Owner, and issues Access Tokens after getting proper authorization. In this case, Auth0.
- User Agent: the agent used by the Resource Owner to interact with the Application, for example a browser or a native application.
Link to this headingAuthorization Code
- Get a token for your email app to access your google mail.
Protocol Flow:
sequenceDiagram
Application (Client) ->> User (Resource Owner): 1. Authorization Request
User (Resource Owner) ->> Application (Client): 2. Authorization Grant
Application (Client) ->> Authorization Server: 3. Authorization Grant
Authorization Server ->> Application (Client): 4. Access Token
Application (Client) ->> Resource Server: 5. Access Token
Resource Server ->> Application (Client): 6. Protected Resource
Link to this headingParameters
https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml
| client_id | authorization request, token request |
| response_type | authorization request |
| redirect_uri | authorization request, token request |
| scope | authorization request, authorization response, token request, token response |
| state | authorization request, authorization response |
| code | authorization response, token request |
| error | authorization response, token response |
| error_description | authorization response, token response |
| error_uri | authorization response, token response |
| access_token | authorization response, token response |
| token_type | authorization response, token response |
| expires_in | authorization response, token response |
| refresh_token | token request, token response |
| display | authorization request |
| max_age | authorization request |
| ui_locales | authorization request |
| claims_locales | authorization request |
| id_token_hint | authorization request |
| login_hint | authorization request |
| acr_values | authorization request |
| registration | authorization request |
| request | authorization request |
| request_uri | authorization request |
| id_token | authorization response, access token response |
| session_state | authorization response, access token response |
| client_assertion | token request |
| client_assertion_type | token request |
| code_challenge | authorization request |
| code_challenge_method | authorization request |
| claim_token | client request, token endpoint |
| pct | client request, token endpoint |
| pct | authorization server response, token endpoint |
| rpt | client request, token endpoint |
| ticket | client request, token endpoint |
| upgraded | authorization server response, token endpoint |
| vtr | authorization request, token request |
| resource | authorization request, token request |
| requested_token_type | token request |
| subject_token_type | token request |
| actor_token_type | token request |
| issued_token_type | token response |
| response_mode | Authorization Request |
| nfv_token | Access Token Response |
| iss | authorization request, authorization response |
| ace_client_recipientid | client-rs request |
| ace_server_recipientid | rs-client response |
| authorization_details | authorization request, token request, token response |
| dpop_jkt | authorization request |
Link to this headingAttacks
Link to this headingReusing Account tokens
Check that an old Code is expired after one use. Or after a short time period.
Link to this headingInsufficient redirect URI validation
Check the redirect URI for an attacker controlled site.
Check for a 302 Redirect on the scoped domain
Link to this headingCSRF
Check that State parameter
- Make sure that it is checked by the server
- Make sure that it is not a static value
- Make sure that if you remove the parameter all together that the request fails.
Otherwise it can be subject to CSRF attacks
Link to this headingGoogle OAUTH Example
Setup:
- Go to https://console.cloud.google.com/apis/credentials and set up a new OAuth 2.0 Client IDs
- Create Credentials -> OAuth client ID -> Web Application
- Set Authorized JavaScript origins to
http://test.generalzero.org:5000/ - Set Authorized redirect URIs to
http://test.generalzero.org:5000/oauth/google/callback - Set the client_id and client secret to env variables.
Flow:
- On visit to
http://test.generalzero.org:5000/there is a link to/oauth/google - When the user visits
/oauth/googlethe site returns a 302 redirect to Googles OAUTH endpoint with some parameters.- Google Parameters
{"response_type": "code", "client_id":"{OAuth_Client_ID}", "redirect_uri": "http%3A%2F%test.generalzero.org%3A5000%2Foauth%2Fgoogle%2Fcallback", "scope": "email", "state":"fb139654c956ac64dfb39e0000000000"} - The site also sets a oauth_state cookie with the test.generalzero.org domain
oauth_state=fb139654c956ac64dfb39e0000000000; HttpOnly; SameSite=Lax
- Google Parameters
- Google Does its flow and then makes a 302 redirect back to the redirect_uri.
- Parameters:
{"state":"fb139654c956ac64dfb39e0000000000", "code":"4%2F0AcvDMrDA-4AAAAAAAAAA8ffzMy4XJ0qSDFEt_1SfYAAAAxSl7YBDfFSdtALVsQL4JmYfdQ", "scope":"email+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email", "authuser":"0", "prompt":"none"
- Parameters:
- On the
/oauth/google/callbackthe endpoint checks that the state paramater is the same as the set oauth_state cookie that is submitted on the request from the browser. - This means that you have a valid token and code to query google as the server.
- THE SERVER makes a request to google to retrieve an access token.
- Parameters:
{"grant_type":"authorization_code", "code":"4%2F0AcvDMrDA-4AAAAAAAAAA8ffzMy4XJ0qSDFEt_1SfYAAAAxSl7YBDfFSdtALVsQL4JmYfdQ", "redirect_uri":"http%3A%2F%test.generalzero.org%3A5000%2Foauth%2Fgoogle%2Fcallback", "client_id":"{OAuth_Client_ID}", "client_secret":"{OAuth_Client_SECRET}"}
- Parameters:
- Now the server has the access_token from google to request information about the user.
- https://www.googleapis.com/oauth2/v2/userinfo with the Header
Authorization: Bearer ${access_token}
- https://www.googleapis.com/oauth2/v2/userinfo with the Header
Test Code:
;
;
;
;
;
;
;
"static";
"/oauth/google",;
"/oauth/google/callback", ;
PORT,;